package com.pwc.conversionTool.XML;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

/**
 * dependency dom4j lib and appache common io basic function for reading xml
 */
public class XMLBase {

	private Document document = null;

	/**
	 * give a empty constructor
	 */
	public XMLBase() {

	}

	/**
	 * read xml to document
	 * 
	 * @param xml
	 * @throws DocumentException
	 */
	public void readStringToXML(String xml) throws DocumentException {
		SAXReader reader = new SAXReader();
		document = reader.read(new StringReader(xml));
	}

	
	/**
	 * 
	 * is this string xml
	 * */
	public static boolean isXML(String xml) {
		SAXReader reader = new SAXReader();
		try {
			Document testDocument = reader.read(new StringReader(xml));
		} catch (Exception e) {

			return false;
		}
		
		return true;

	}

	/**
	 * read the string xml and save it to file
	 * 
	 * @param xml
	 * @throws DocumentException
	 * @throws IOException
	 */
	public void saveDocument(String xml) throws DocumentException, IOException {
		readStringToXML(xml);
	}

	/**
	 * get single file by xpath
	 * 
	 * @param xPath
	 * @return
	 */
	public String getSingleStringValue(String xPath) {
		String result = null;
		Node node = document.selectSingleNode(xPath);
		if (node != null)
			result = node.getStringValue();
		return result;
	}

	/**
	 * set single node using xpath
	 * 
	 * @param xPath
	 * @param value
	 */
	public void setSingleStringValue(String xPath, String value) {
		Node node = document.selectSingleNode(xPath);
		node.setText(value);
	}

	/**
	 * add node
	 * 
	 * @param xPath
	 *            location of the node
	 * @param nodeName
	 * @param value
	 */
	public void addNodeByXpath(String xPath, String nodeName, String value) {
		Element root = (Element) document.selectSingleNode(xPath);
		Element temp = root.addElement(nodeName);
		temp.setText(value);
	}

	/**
	 * delete node by xPath
	 * 
	 * @param xPath
	 * @param value
	 */
	public void deleteNodeByXpath(String xPath) {
		List<Element> data = document.selectNodes(xPath);
		for (Element element : data) {
			element.detach();
		}
	}

	/**
	 * get list of file by xPath
	 * 
	 * @param xPath
	 * @return
	 */
	public List<String> getStringArray(String xPath) {
		List<String> list = new ArrayList<String>();
		List<Element> composites = document.selectNodes(xPath);
		if (composites != null) {
			for (Element e : composites) {
				list.add(e.getStringValue());
			}
		}
		return list;
	}
	
	/**
	 * get values by xpath
	 * @param xPath
	 * @return
	 */
	public List<String> getValuesByXpath(String xPath)
	{
		List<String> result=new ArrayList<String>();
		
		List<Node> list=document.selectNodes(xPath);
		
		for (Node node : list) {
			result.add(node.getStringValue()) ;
		}
		
		return result;
		
	}

	/**
	 * get childe key and value from a path
	 * 
	 * @param xPath
	 * @return
	 */
	public Map<String, String> getXMLMap(String xPath) {
		Map<String, String> hashMap = new HashMap<String, String>();
		Element data = (Element) document.selectSingleNode(xPath);
		List<Node> composites = data.elements();
		if (composites != null) {
			for (Node e : composites) {
				hashMap.put(e.getName(), e.getText());
			}
		}
		return hashMap;
	}

	/**
	 * overrided to string function
	 */
	public String toString() {
		return document.asXML();
	}

}
